import 'dart:async';

import 'package:alipay_kit/alipay_kit.dart';
import 'package:fluwx/fluwx.dart';
import 'package:get/get.dart';
import 'package:ball_lion/entity/pay/subscribe_entity.dart';
import 'package:ball_lion/server/api/other_api.dart';
import 'package:ball_lion/utils/utils.dart';
import 'package:ball_lion/utils/web_pay.dart';
import 'package:ball_lion/module/pay/pay_bottom_sheet.dart';
import 'package:ball_lion/entity/pay/recharge_entity.dart';
import 'package:ball_lion/entity/pay/usable_coupon.dart';
import 'package:ball_lion/server/api/pay_api.dart';
import 'package:ball_lion/utils/toast_utils.dart';
import 'package:ball_lion/utils/user.dart';

class PayBottomLogic extends GetxController {
  late final PayInfo _payInfo;
  double _price = 0;
  double _priceReal = 0;
  double gold = User.info?.qiuGold ?? 0;
  bool payToBuy = false;
  double _needPay = 0;
  PayMode? _payMode;
  int _usable = 0;
  bool _click = true;
  bool _hasEnd = false;
  bool _subcardsUsable = false;

  List<PayMode>? payList;
  late final StreamSubscription? alipayListener;
  late WeChatResponseSubscriber wechatListener;
  late final StreamSubscription? webPayListener;

  UsableCouponEntity? _select;
  UsableCouponEntity? get select => _select;
  int get usable => _usable;
  PayMode? get payMode => _payMode;
  PayInfo get payInfo => _payInfo;
  bool get click => _click;
  double get priceReal => _priceReal;
  double get price => _price;
  double get needPay => _needPay;
  bool get hasEnd => _hasEnd;
  bool get subcardsUsable => _subcardsUsable;
  SubscribleCardEntity? _cardSelect;
  SubscribleCardEntity? get cardSelect => _cardSelect;

  // set subcardsUsable(bool value) {
  //   _subcardsUsable = value;
  //   update();
  // }

  set hasEnd(bool value) {
    _hasEnd = value;
    update();
  }

  set needPay(double value) {
    _needPay = value.toStringAsFixed(2).toDouble()!;
    update();
  }

  set price(double value) {
    _price = value.toStringAsFixed(2).toDouble()!;
    update();
  }

  set priceReal(double value) {
    _priceReal = value.toStringAsFixed(2).toDouble()!;
    update();
  }

  set click(bool value) {
    _click = value;
    update();
  }

  set payInfo(PayInfo value) {
    _payInfo = value;
    update();
  }

  set payMode(PayMode? value) {
    _payMode = value;
    update();
  }

  set usable(int value) {
    _usable = value;
    update();
  }

  set cardSelect(SubscribleCardEntity? value) {
    _cardSelect = value;
    // if (value == null) {
    //   priceReal = 0;
    //   payToBuy = false;
    //   needPay = 0;
    // } else {
    //   priceReal = price;
    //   payToBuy = false;
    //   needPay = 0;
    // }
    if (value == null && _select != null) {
      return;
    }
    if (value != null) {
      priceReal = 0;
    } else {
      priceReal = price;
    }
    if (priceReal > gold) {
      payToBuy = true;
      needPay = priceReal - gold;
    } else {
      payToBuy = false;
      needPay = 0;
    }
    update();
  }

  set select(UsableCouponEntity? value) {
    _select = value;
    if (value == null && _cardSelect != null) {
      return;
    }
    priceReal = price - (_select?.gold ?? 0);
    if (priceReal > gold) {
      payToBuy = true;
      needPay = priceReal - gold;
    }
    update();
  }

  @override
  void onInit() {
    alipayListener = AlipayKitPlatform.instance.payResp().listen((event) async {
      if (event.resultStatus == 9000) {
        Utils.onEvent('pay_done');
        Toast.text("支付成功");
        if (!hasEnd) {
          Get.back(result: const PayResult(toPay: PayStatus.directPay));
        }
      } else if (event.resultStatus == 6001) {
        if (!hasEnd) Get.back(result: const PayResult(toPay: PayStatus.failed));
        click = true;
        Toast.text('取消支付');
      } else {
        if (!hasEnd) Get.back(result: const PayResult(toPay: PayStatus.failed));
      }
      hasEnd = true;
    });
    wechatListener = (response) {
      if (response is WeChatPaymentResponse) {
        if (response.isSuccessful) {
          Utils.onEvent('pay_done');
          Toast.text("支付成功");
          if (!hasEnd)
            Get.back(result: const PayResult(toPay: PayStatus.directPay));
        } else if (response.errCode == -2) {
          if (!hasEnd)
            Get.back(result: const PayResult(toPay: PayStatus.failed));
          click = true;
          Toast.text('取消支付');
        } else {
          if (!hasEnd)
            Get.back(result: const PayResult(toPay: PayStatus.failed));
        }
        hasEnd = true;
      }
    };
    Fluwx().addSubscriber(wechatListener);
    webPayListener = WebPay().payResp().listen((event) {
      Utils.onEvent('pay_done');
      if (event == WebPayResult.success) {
        Get.back(result: const PayResult(toPay: PayStatus.directPay));
      } else if (event == WebPayResult.fail) {
        Get.back(result: const PayResult(toPay: PayStatus.directPay));
      }
    });
    super.onInit();
  }

  @override
  void onReady() {
    init();
    getPayList();
    requestSubcards();
    super.onReady();
  }

  Future init() async {
    await User.fetchUserInfo(fetchFocus: false);
    gold = User.info?.qiuGold ?? 0.toStringAsFixed(2).toDouble()!;
    if (payInfo.coupons.hasValue) {
      for (final element in payInfo.coupons!) {
        if (element.autoSelect == 1) {
          select = element;
        }
        if (element.canUse == 1) {
          usable += 1;
        }
      }
    }

    price = double.parse(payInfo.price);
    priceReal = price - (select?.gold ?? 0);
    if (priceReal > gold) {
      payToBuy = true;
      needPay = priceReal - gold;
    }
    update();
  }

  Future getPayList() async {
    var list = await OtherApi.getAppList('app_pay_list');
    if (list.hasValue) {
      var index = list!.indexWhere((element) => element.extInfo == "1");
      payList = list.map((e) => PayMode.fromResource(e)).toList();
      if (index != -1) {
        payMode = payList![index];
      } else {
        payMode = payList?.first;
      }
    }
    update();
  }

  Future requestSubcards() async {
    if (payInfo.ownerId == null) {
      return;
    }
    payInfo.subCards = await PayApi.querySubCards(payInfo.ownerId ?? "");
    _subcardsUsable = payInfo.subCards?.any(
            (element) => element.enable == true && element.invalid == true) ??
        false;
    update();
  }

  Future pay() async {
    if (User.info?.selfExpert == true) {
      Toast.text('公司内部专家不支持消费');
      return;
    }
    if (payToBuy) {
      PayEntity? direct = await PayApi.directPay(
          buyCouponGold: select?.gold,
          buyCouponId: select?.id.toString(),
          buyGold: price,
          buyId: payInfo.buyId,
          buyType: payInfo.payScene.type,
          payAmt: needPay.toStringAsFixed(2).toDouble(),
          payMode: payMode);
      if (direct == null)
        return Get.back(result: const PayResult(toPay: PayStatus.failed));
      await PayApi.androidPay(payMode, direct.payCertificate!);
    } else {
      Get.back(
          result: PayResult(
              toPay: PayStatus.goldPay, coupon: select, subcard: cardSelect));
    }
  }

  @override
  void onClose() {
    alipayListener?.cancel();
    WebPay().close(webPayListener);
    Fluwx().removeSubscriber(wechatListener);
    super.onClose();
  }
}
